#ifndef VIDEOCAPTURE_LOOPBACK_LOOPBACK_H
#define VIDEOCAPTURE_LOOPBACK_LOOPBACK_H

#include <opencv2/opencv.hpp>
#include <thread>
#include <string>

class VirtualCamera {
private:
    int virtual_cam{};
    int width{};
    int height{};

    void init_virtual_cam() const;

public:
    VirtualCamera(int virtual_index, int width, int height);
    VirtualCamera();
    bool write_frame(const cv::Mat& frame) const;
    void release() const;
};

class VideoCaptureLoopback {
private:
    cv::VideoCapture cam;
    int width{};
    int height{};
    int fps{};
    cv::Mat cur_frame;

    // local video loop control
    uint64_t max_frame;
    uint64_t cur_frame_count;

    VirtualCamera virtual_cam;

    // Capturing thread related
    std::thread capturing_thread;
    std::mutex frame_mutex;
    bool keep_running{};

    void initializing(int width, int height, int fps);

    void capturing();

public:
    VideoCaptureLoopback(int index, int virtual_index, int width, int height, int fps);
    VideoCaptureLoopback(std::string index, int virtual_index, int width, int height, int fps);
    VideoCaptureLoopback();
    ~VideoCaptureLoopback();
    void release();
    bool isOpened();
    void read_frame(cv::OutputArray image);
    cv::VideoCapture& operator >> (CV_OUT cv::Mat& image);
};

#endif //VIDEOCAPTURE_LOOPBACK_LOOPBACK_H